module controller.SearchController;

import vibe.http.server : HTTPServerRequest, HTTPServerResponse;
import vibe.data.json : Json, serializeToJsonString, parseJsonString;

import model.Teleplay;
import model.Movie;
import model.Animation;
import repository.TeleplayRepo;
import repository.MovieRepo;
import repository.AnimationRepo;

import utils.ObjMapping : ObjMapping;
import utils.RespData : RespData;

import utils.DataCache;
import utils.CacheKey : CacheKey;
import utils.SecurityVerification : signValidator;

// import std.stdio;

TeleplayRepo _tRepo; // 电视剧仓储
MovieRepo _mRepo; // 电影仓储
AnimationRepo _aRepo; // 动漫仓储

static this ()
{
    _tRepo = new TeleplayRepo();
    _mRepo = new MovieRepo();
    _aRepo = new AnimationRepo();
}

static ~this ()
{
    destroy(_tRepo);
    destroy(_mRepo);
    destroy(_aRepo);
}

/** 
 * 首页视频搜索
 */
void search (HTTPServerRequest req, HTTPServerResponse resp)
{
    import std.algorithm : canFind;
    import std.string : format;

    string vcate = req.query.get("vcate", "");
    string keywords = req.query.get("keywords", "");
    string sign = req.query.get("sign", "");

    if (vcate == "" || keywords == "" || sign == "")
    {
        resp.writeJsonBody(RespData.newData(400, "错误的请求"));
        return;
    }

    import std.format : format;

    string reqParamsStr = format("%s%s", vcate, keywords);
    if (!signValidator(reqParamsStr, sign))
    {
        resp.writeJsonBody(RespData.newData(403, "签名不正确！"), 403);
        return;
    }

    string cachekey = format("%s_%s_%s", CacheKey.SEARCH_RESULT_CACHE, vcate, keywords);

    // 缓存中有数据直接取出返回
    auto data = cacheData.get(cachekey);
    if (!data.isNull)
    {
        resp.writeJsonBody(RespData.newData(200, "ok", data.get));
        return;
    }

    Json respData;
    switch (vcate)
    {
    case "1":
        TeleplayDto[] searchResults = [];
        Teleplay[] list = _tRepo.getTeleplayList();
        foreach (t; list)
        {
            if (canFind(t.name, keywords))
            {
                searchResults ~= ObjMapping.mappingToObject!(TeleplayDto, Teleplay)(t);
            }
        }
        // 设置缓存
        string jsonData = serializeToJsonString(searchResults);
        cacheData.put(cachekey, jsonData);
        respData = RespData.newData(200, "ok", jsonData);
        break;

    case "2":
        MovieDto[] searchResults = [];
        Movie[] list = _mRepo.getMovieList();
        foreach (m; list)
        {
            if (canFind(m.name, keywords))
            {
                searchResults ~= ObjMapping.mappingToObject!(MovieDto, Movie)(m);
            }
        }
        // 设置缓存
        string jsonData = serializeToJsonString(searchResults);
        cacheData.put(cachekey, jsonData);
        respData = RespData.newData(200, "ok", jsonData);
        break;

    case "3":
        AnimationDto[] searchResults = [];
        Animation[] list = _aRepo.getAnimationList();
        foreach (a; list)
        {
            if (canFind(a.name, keywords))
            {
                searchResults ~= ObjMapping.mappingToObject!(AnimationDto, Animation)(a);
            }
        }
        // 设置缓存
        string jsonData = serializeToJsonString(searchResults);
        cacheData.put(cachekey, jsonData);
        respData = RespData.newData(200, "ok", jsonData);
        break;

    default:
        break;
    }

    resp.writeJsonBody(respData);
}
